package com.zhou;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.arithmetic.*;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.parser.Node;
import net.sf.jsqlparser.parser.SimpleNode;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.*;
import net.sf.jsqlparser.statement.alter.Alter;
import net.sf.jsqlparser.statement.alter.AlterSession;
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
import net.sf.jsqlparser.statement.comment.Comment;
import net.sf.jsqlparser.statement.create.index.CreateIndex;
import net.sf.jsqlparser.statement.create.schema.CreateSchema;
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.view.AlterView;
import net.sf.jsqlparser.statement.create.view.CreateView;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.drop.Drop;
import net.sf.jsqlparser.statement.execute.Execute;
import net.sf.jsqlparser.statement.grant.Grant;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.merge.Merge;
import net.sf.jsqlparser.statement.merge.MergeInsert;
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import net.sf.jsqlparser.statement.upsert.Upsert;
import net.sf.jsqlparser.statement.values.ValuesStatement;

import java.util.*;

/**
 * 嵌套查询这种情况暂时不写
 * 先把简单的单表查询、连多、多表查询搞定
 */
public class MyJSqlVisitor implements StatementVisitor, SelectVisitor, SelectItemVisitor, ExpressionVisitor, FromItemVisitor, GroupByVisitor, OrderByVisitor, ItemsListVisitor {

    private Statement statement;

    public MyJSqlVisitor() {
    }

    public MyJSqlVisitor(Statement statement) {
        this.statement = statement;
    }

    public Statement getStatement() {
        return statement;
    }

    public void setStatement(Statement statement) {
        this.statement = statement;
    }

    public static final ThreadLocal<Select> THREAD_LOCAL_SELECT = new ThreadLocal<>();
    public static final Map<String, Object> MAP = new HashMap<>();

    @Override
    public void visit(BitwiseRightShift bitwiseRightShift) {

    }

    @Override
    public void visit(BitwiseLeftShift bitwiseLeftShift) {

    }

    @Override
    public void visit(NullValue nullValue) {

    }

    @Override
    public void visit(Function function) {
        ExpressionList parameters = function.getParameters();
        List<Expression> expressions = parameters.getExpressions();
        for (Expression expression : expressions) {
            MAP.put(String.valueOf(expression.hashCode()), function);
            expression.accept(this);
        }
        function.setName(function.getName().replace("\"", ""));
        ReplaceUtil.replaceFunction(function);
    }

    private void processCaseExpression(CaseExpression caseExpression) {
        expressionAcceptAndPutToMap(caseExpression.getSwitchExpression(), caseExpression);
        List<WhenClause> whenClauses = caseExpression.getWhenClauses();
        for (WhenClause whenClause : whenClauses) {
            expressionAcceptAndPutToMap(whenClause.getWhenExpression(), caseExpression);
            expressionAcceptAndPutToMap(whenClause.getThenExpression(), caseExpression);
        }
        expressionAcceptAndPutToMap(caseExpression.getElseExpression(), caseExpression);
    }

    @Override
    public void visit(SignedExpression signedExpression) {

    }

    @Override
    public void visit(JdbcParameter jdbcParameter) {

    }

    @Override
    public void visit(JdbcNamedParameter jdbcNamedParameter) {

    }

    @Override
    public void visit(DoubleValue doubleValue) {

    }

    @Override
    public void visit(LongValue longValue) {

    }

    @Override
    public void visit(HexValue hexValue) {

    }

    @Override
    public void visit(DateValue dateValue) {

    }

    @Override
    public void visit(TimeValue timeValue) {

    }

    @Override
    public void visit(TimestampValue timestampValue) {

    }

    @Override
    public void visit(Parenthesis parenthesis) {
        expressionAcceptAndPutToMap(parenthesis.getExpression(), parenthesis);
    }

    @Override
    public void visit(StringValue stringValue) {

    }

    @Override
    public void visit(Addition addition) {
        expressionAcceptAndPutToMap(addition.getLeftExpression(), addition);
        expressionAcceptAndPutToMap(addition.getRightExpression(), addition);
    }

    @Override
    public void visit(Division division) {
        expressionAcceptAndPutToMap(division.getLeftExpression(), division);
        expressionAcceptAndPutToMap(division.getRightExpression(), division);
    }

    @Override
    public void visit(IntegerDivision integerDivision) {

    }

    @Override
    public void visit(Multiplication multiplication) {
        expressionAcceptAndPutToMap(multiplication.getLeftExpression(), multiplication);
        expressionAcceptAndPutToMap(multiplication.getRightExpression(), multiplication);
    }

    @Override
    public void visit(Subtraction subtraction) {
        expressionAcceptAndPutToMap(subtraction.getLeftExpression(), subtraction);
        expressionAcceptAndPutToMap(subtraction.getRightExpression(), subtraction);
    }

    /**
     * 处理 and 操作符
     *
     * @param andExpression and 操作符
     */
    @Override
    public void visit(AndExpression andExpression) {
        if (andExpression != null) {
            expressionAcceptAndPutToMap(andExpression.getLeftExpression(), andExpression);
            expressionAcceptAndPutToMap(andExpression.getRightExpression(), andExpression);
        }
    }

    @Override
    public void visit(OrExpression orExpression) {
        if (orExpression != null) {
            expressionAcceptAndPutToMap(orExpression.getLeftExpression(), orExpression);
            expressionAcceptAndPutToMap(orExpression.getRightExpression(), orExpression);
        }
    }

    @Override
    public void visit(XorExpression xorExpression) {

    }

    @Override
    public void visit(Between between) {
        Expression leftExpression = between.getLeftExpression();
        Expression betweenExpressionStart = between.getBetweenExpressionStart();
        Expression betweenExpressionEnd = between.getBetweenExpressionEnd();
        expressionAcceptAndPutToMap(leftExpression, between);
        expressionAcceptAndPutToMap(betweenExpressionStart, between);
        expressionAcceptAndPutToMap(betweenExpressionEnd, between);
    }

    @Override
    public void visit(EqualsTo equalsTo) {
        expressionAcceptAndPutToMap(equalsTo.getLeftExpression(), equalsTo);
        expressionAcceptAndPutToMap(equalsTo.getRightExpression(), equalsTo);
    }

    private void expressionAccept(Expression expression) {
        if (expression != null) {
            expression.accept(this);
        }
    }

    private void expressionAcceptAndPutToMap(Expression expression, Expression parentExpression) {
        if (expression != null) {
            MAP.put(String.valueOf(expression.hashCode()), parentExpression);
            expression.accept(this);
        }
    }

    private void expressionListAccept(List<? extends Expression> expressions) {
        if (expressions != null) {
            for (Expression expression : expressions) {
                expression.accept(this);
            }
        }
    }

    @Override
    public void visit(GreaterThan greaterThan) {
        replacePagination(greaterThan);
        expressionAcceptAndPutToMap(greaterThan.getLeftExpression(), greaterThan);
        expressionAcceptAndPutToMap(greaterThan.getRightExpression(), greaterThan);
    }

    @Override
    public void visit(GreaterThanEquals greaterThanEquals) {
        expressionAcceptAndPutToMap(greaterThanEquals.getLeftExpression(), greaterThanEquals);
        expressionAcceptAndPutToMap(greaterThanEquals.getRightExpression(), greaterThanEquals);
    }

    @Override
    public void visit(InExpression inExpression) {

    }

    @Override
    public void visit(FullTextSearch fullTextSearch) {

    }

    @Override
    public void visit(IsNullExpression isNullExpression) {

    }

    @Override
    public void visit(IsBooleanExpression isBooleanExpression) {

    }

    @Override
    public void visit(LikeExpression likeExpression) {

    }

    @Override
    public void visit(MinorThan minorThan) {
        expressionAcceptAndPutToMap(minorThan.getLeftExpression(), minorThan);
        expressionAcceptAndPutToMap(minorThan.getRightExpression(), minorThan);
    }

    @Override
    public void visit(MinorThanEquals minorThanEquals) {
        replacePagination(minorThanEquals);
        expressionAcceptAndPutToMap(minorThanEquals.getLeftExpression(), minorThanEquals);
        expressionAcceptAndPutToMap(minorThanEquals.getRightExpression(), minorThanEquals);
    }

    private void replacePagination(ComparisonOperator comparisonOperator) {
        Expression leftExpression = comparisonOperator.getLeftExpression();
        Expression rightExpression = comparisonOperator.getRightExpression();
        if (leftExpression instanceof Column) {
            Column column = (Column) leftExpression;
            String columnName = column.getColumnName();
            if (Constants.ROWNUM.equalsIgnoreCase(columnName) || Constants.ROWNO.equalsIgnoreCase(columnName)) {
                // 获取 当前表达式 所在的那个 查询语句 对应的节点
                Node parent = comparisonOperator.getASTNode().jjtGetParent().jjtGetParent();
                // 获取父节点中 子查询 对应的节点
                for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
                    SimpleNode child = (SimpleNode) parent.jjtGetChild(i);
                    if (child.jjtGetValue() instanceof SubSelect) {
                        SubSelect subSelect = (SubSelect) child.jjtGetValue();
                        SelectBody selectBody = subSelect.getSelectBody();
                        if (rightExpression instanceof Addition) {
                            Addition addition = (Addition) rightExpression;
                            PlainSelect plainSelect = (PlainSelect) selectBody;
                            // 添加 mysql 分页
                            Limit limit = new Limit();
                            limit.setRowCount(addition.getRightExpression());
                            limit.setOffset(addition.getLeftExpression());
                            plainSelect.setLimit(limit);
                        }
                        Select select = THREAD_LOCAL_SELECT.get();
                        select.setSelectBody(selectBody);
                        return;
                    }
                }
            }
        } else if (rightExpression instanceof Column) {
            Column column = (Column) rightExpression;
            String columnName = column.getColumnName();
            if (Constants.ROWNUM.equalsIgnoreCase(columnName) || Constants.ROWNO.equalsIgnoreCase(columnName)) {
                // 获取 当前表达式 所在的那个 查询语句 对应的节点
                Node parent = comparisonOperator.getASTNode().jjtGetParent().jjtGetParent();
                // 获取父节点中 子查询 对应的节点
                for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
                    SimpleNode child = (SimpleNode) parent.jjtGetChild(1);
                    if (child.jjtGetValue() instanceof SubSelect) {
                        SubSelect subSelect = (SubSelect) child.jjtGetValue();
                        SelectBody selectBody = subSelect.getSelectBody();
                        Select select = THREAD_LOCAL_SELECT.get();
                        select.setSelectBody(selectBody);
                        return;
                    }
                }
            }
        }
    }

    @Override
    public void visit(NotEqualsTo notEqualsTo) {
        expressionAcceptAndPutToMap(notEqualsTo.getLeftExpression(), notEqualsTo);
        expressionAcceptAndPutToMap(notEqualsTo.getRightExpression(), notEqualsTo);
    }

    @Override
    public void visit(Column column) {
        ReplaceUtil.replaceColumn(column);
    }

    @Override
    public void visit(Table table) {
        //if (Objects.isNull(table.getAlias())){
        //    Alias alias = new Alias(UUID.nameUUIDFromBytes(table.getName().getBytes()).toString());
        //    table.setAlias(alias);
        //}
    }

    @Override
    public void visit(SubSelect subSelect) {
        // 如果子查询没有别名，添加别名
        if (Objects.isNull(subSelect.getAlias())) {
            if (MAP.containsKey(String.valueOf(subSelect.hashCode()))) {
                Object o = MAP.get(String.valueOf(subSelect.hashCode()));
                if (o instanceof SelectExpressionItem) {
                    SelectExpressionItem item = (SelectExpressionItem) o;
                    if (item.getAlias() == null) {
                        String aliasName = getRandomString(6);
                        Alias alias = new Alias(aliasName);
                        subSelect.setAlias(alias);
                    }
                }
                // 如果是表达式中的子查询，不添加别名
                else if (o instanceof Expression) {

                }
            }
            // 如果没有父节点，添加别名
            else {
                String aliasName = getRandomString(6);
                Alias alias = new Alias(aliasName);
                subSelect.setAlias(alias);
            }
        }

        SelectBody selectBody = subSelect.getSelectBody();
        if (selectBody != null) {
            selectBody.accept(this);
        }
    }

    @Override
    public void visit(ExpressionList expressionList) {
        List<Expression> expressions = expressionList.getExpressions();
        expressions.remove(0);
        for (Expression expression : expressions) {
            expressionAccept(expression);
        }
    }

    @Override
    public void visit(NamedExpressionList namedExpressionList) {

    }

    @Override
    public void visit(MultiExpressionList multiExprList) {

    }

    @Override
    public void visit(SubJoin subJoin) {
    }

    @Override
    public void visit(LateralSubSelect lateralSubSelect) {

    }

    @Override
    public void visit(ValuesList valuesList) {

    }

    @Override
    public void visit(TableFunction tableFunction) {

    }

    @Override
    public void visit(ParenthesisFromItem parenthesisFromItem) {
        System.out.println("parenthesisFromItem = " + parenthesisFromItem);
    }

    @Override
    public void visit(CaseExpression caseExpression) {
        processCaseExpression(caseExpression);
    }

    @Override
    public void visit(WhenClause whenClause) {

    }

    @Override
    public void visit(ExistsExpression existsExpression) {

    }

    @Override
    public void visit(AnyComparisonExpression anyComparisonExpression) {

    }

    @Override
    public void visit(Concat concat) {
        try {
            Expression expression = CCJSqlParserUtil.parseExpression("concat(" + concat.toString().replace("||", ",") + ")");
            String key = String.valueOf(concat.hashCode());
            if (MAP.containsKey(key)) {
                Object m = MAP.get(key);
                if (m instanceof SelectExpressionItem) {
                    SelectExpressionItem selectExpressionItem = (SelectExpressionItem) m;
                    selectExpressionItem.setExpression(expression);
                    expression.accept(this);
                } else if (m instanceof Function) {
                    Function function = (Function) m;
                    ExpressionList parameters = function.getParameters();
                    List<Expression> expressions = parameters.getExpressions();
                    for (Expression ex : expressions) {
                        if (Objects.equals(ex, concat)) {
                            int index = expressions.indexOf(ex);
                            expressions.set(index, expression);
                            expression.accept(this);
                        }
                    }
                }
                MAP.remove(key);
            }
        } catch (JSQLParserException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void visit(Matches matches) {

    }

    @Override
    public void visit(BitwiseAnd bitwiseAnd) {

    }

    @Override
    public void visit(BitwiseOr bitwiseOr) {

    }

    @Override
    public void visit(BitwiseXor bitwiseXor) {

    }

    @Override
    public void visit(CastExpression castExpression) {

    }

    @Override
    public void visit(TryCastExpression tryCastExpression) {

    }

    @Override
    public void visit(Modulo modulo) {

    }

    @Override
    public void visit(AnalyticExpression analyticExpression) {

    }

    @Override
    public void visit(ExtractExpression extractExpression) {

    }

    @Override
    public void visit(IntervalExpression intervalExpression) {

    }

    @Override
    public void visit(OracleHierarchicalExpression oracleHierarchicalExpression) {

    }

    @Override
    public void visit(RegExpMatchOperator regExpMatchOperator) {

    }

    @Override
    public void visit(JsonExpression jsonExpression) {

    }

    @Override
    public void visit(JsonOperator jsonOperator) {

    }

    @Override
    public void visit(RegExpMySQLOperator regExpMySQLOperator) {

    }

    @Override
    public void visit(UserVariable userVariable) {

    }

    @Override
    public void visit(NumericBind numericBind) {

    }

    @Override
    public void visit(KeepExpression keepExpression) {

    }

    @Override
    public void visit(MySQLGroupConcat mySQLGroupConcat) {

    }

    @Override
    public void visit(ValueListExpression valueListExpression) {

    }

    @Override
    public void visit(RowConstructor rowConstructor) {

    }

    @Override
    public void visit(RowGetExpression rowGetExpression) {

    }

    @Override
    public void visit(OracleHint oracleHint) {

    }

    @Override
    public void visit(TimeKeyExpression timeKeyExpression) {

    }

    @Override
    public void visit(DateTimeLiteralExpression dateTimeLiteralExpression) {

    }

    @Override
    public void visit(NotExpression notExpression) {

    }

    @Override
    public void visit(NextValExpression nextValExpression) {

    }

    @Override
    public void visit(CollateExpression collateExpression) {

    }

    @Override
    public void visit(SimilarToExpression similarToExpression) {

    }

    @Override
    public void visit(ArrayExpression arrayExpression) {

    }

    @Override
    public void visit(ArrayConstructor arrayConstructor) {

    }

    @Override
    public void visit(VariableAssignment variableAssignment) {

    }

    @Override
    public void visit(XMLSerializeExpr xmlSerializeExpr) {

    }

    @Override
    public void visit(TimezoneExpression timezoneExpression) {

    }

    @Override
    public void visit(JsonAggregateFunction jsonAggregateFunction) {

    }

    @Override
    public void visit(JsonFunction jsonFunction) {

    }

    @Override
    public void visit(ConnectByRootOperator connectByRootOperator) {

    }

    @Override
    public void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {

    }

    @Override
    public void visit(SavepointStatement savepointStatement) {

    }

    @Override
    public void visit(RollbackStatement rollbackStatement) {

    }

    @Override
    public void visit(Comment comment) {

    }

    @Override
    public void visit(Commit commit) {

    }

    @Override
    public void visit(Delete delete) {

    }

    @Override
    public void visit(Update update) {
        ArrayList<UpdateSet> updateSets = update.getUpdateSets();
        for (UpdateSet updateSet : updateSets) {
            expressionListAccept(updateSet.getColumns());
            expressionListAccept(updateSet.getExpressions());
        }
    }

    @Override
    public void visit(Insert insert) {
        List<Column> columns = insert.getColumns();
        if (columns.get(0).getColumnName().equalsIgnoreCase("id")){
            columns.remove(0);
            ExpressionList itemsList = (ExpressionList) insert.getItemsList();
            itemsList.getExpressions().remove(0);
        }
        for (Column column : columns) {
            expressionAccept(column);
        }
    }

    @Override
    public void visit(Replace replace) {
        ItemsList itemsList = replace.getItemsList();
        itemsList.accept(this);
        expressionListAccept(replace.getExpressions());
        List<Column> columns = replace.getColumns();
        columns.remove(0);
        expressionListAccept(columns);
    }

    @Override
    public void visit(Drop drop) {

    }

    @Override
    public void visit(Truncate truncate) {

    }

    @Override
    public void visit(CreateIndex createIndex) {

    }

    @Override
    public void visit(CreateSchema createSchema) {

    }

    @Override
    public void visit(CreateTable createTable) {

    }

    @Override
    public void visit(CreateView createView) {

    }

    @Override
    public void visit(AlterView alterView) {

    }

    @Override
    public void visit(Alter alter) {

    }

    @Override
    public void visit(Statements statements) {

    }

    @Override
    public void visit(Execute execute) {

    }

    @Override
    public void visit(SetStatement setStatement) {

    }

    @Override
    public void visit(ResetStatement resetStatement) {

    }

    @Override
    public void visit(ShowColumnsStatement showColumnsStatement) {

    }

    @Override
    public void visit(ShowTablesStatement showTablesStatement) {

    }

    @Override
    public void visit(Merge merge) {
        MergeInsert mergeInsert = merge.getMergeInsert();
        List<Column> columns = mergeInsert.getColumns();
        List<Expression> values = mergeInsert.getValues();
        Table table = merge.getTable();
        table.setAlias(null);
        Replace replace = new Replace();
        replace.setTable(table);
        replace.setItemsList(new ExpressionList(values));
        replace.setColumns(columns);
        try {
            Statement parse = CCJSqlParserUtil.parse(replace.toString());
            statement = parse;
        } catch (JSQLParserException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void visit(Select select) {
        SelectBody selectBody = select.getSelectBody();
        if (selectBody != null) {
            THREAD_LOCAL_SELECT.set(select);
            selectBody.accept(this);
        }
    }

    @Override
    public void visit(Upsert upsert) {

    }

    @Override
    public void visit(UseStatement useStatement) {

    }

    @Override
    public void visit(Block block) {

    }

    @Override
    public void visit(PlainSelect plainSelect) {
        SelectBody selectBody = THREAD_LOCAL_SELECT.get().getSelectBody();
        // 处理 where 子句
        // 处理 oracle 分页，暂时忽略在最外层对查询列表进行处理的情况，只保留分页前的查询语句，再加上 mysql 的分页
        Expression where = plainSelect.getWhere();
        if (where != null) {
            if (selectBody != THREAD_LOCAL_SELECT.get().getSelectBody())
                return;
            where.accept(this);
        }

        // 处理 查询列表
        List<SelectItem> selectItems = plainSelect.getSelectItems();
        if (selectItems != null && selectItems.size() > 0) {
            for (SelectItem selectItem : selectItems) {
                selectItem.accept(this);
            }
        }
        // 处理表名或子查询
        FromItem fromItem = plainSelect.getFromItem();
        if (fromItem != null) {
            fromItem.accept(this);
        }

        // 处理连表条件
        List<Join> joins = plainSelect.getJoins();
        if (joins != null) {
            for (Join join : joins) {
                // 处理连表子查询
                FromItem rightItem = join.getRightItem();
                rightItem.accept(this);
                // 处理连接条件
                Collection<Expression> joinOnExpressions = join.getOnExpressions();
                for (Expression joinOnExpression : joinOnExpressions) {
                    joinOnExpression.accept(this);
                }
            }
        }

        // 处理 order by
        List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
        if (orderByElements != null && orderByElements.size() > 0) {
            for (OrderByElement orderByElement : orderByElements) {
                orderByElement.accept(this);
            }
        }

        // 处理 group by
        GroupByElement groupBy = plainSelect.getGroupBy();
        if (groupBy != null) {
            groupBy.accept(this);
        }
    }

    @Override
    public void visit(SetOperationList setOperationList) {

    }

    @Override
    public void visit(WithItem withItem) {

    }

    @Override
    public void visit(ValuesStatement valuesStatement) {

    }

    @Override
    public void visit(DescribeStatement describeStatement) {

    }

    @Override
    public void visit(ExplainStatement explainStatement) {

    }

    @Override
    public void visit(ShowStatement showStatement) {

    }

    @Override
    public void visit(DeclareStatement declareStatement) {

    }

    @Override
    public void visit(Grant grant) {

    }

    @Override
    public void visit(CreateSequence createSequence) {

    }

    @Override
    public void visit(AlterSequence alterSequence) {

    }

    @Override
    public void visit(CreateFunctionalStatement createFunctionalStatement) {

    }

    @Override
    public void visit(CreateSynonym createSynonym) {

    }

    @Override
    public void visit(AlterSession alterSession) {

    }

    @Override
    public void visit(IfElseStatement ifElseStatement) {

    }

    @Override
    public void visit(RenameTableStatement renameTableStatement) {

    }

    @Override
    public void visit(PurgeStatement purgeStatement) {

    }

    @Override
    public void visit(AlterSystemStatement alterSystemStatement) {

    }

    @Override
    public void visit(AllColumns allColumns) {

    }

    @Override
    public void visit(AllTableColumns allTableColumns) {

    }

    @Override
    public void visit(AllValue allValue) {

    }

    @Override
    public void visit(IsDistinctExpression isDistinctExpression) {

    }

    @Override
    public void visit(GeometryDistance geometryDistance) {

    }

    @Override
    public void visit(SelectExpressionItem selectExpressionItem) {
        if (selectExpressionItem.toString().contains(".nextval")){
            try {
                statement = CCJSqlParserUtil.parse("select 1");
                return;
            } catch (JSQLParserException e) {
                throw new RuntimeException(e);
            }
        }
        Expression expression = selectExpressionItem.getExpression();
        if (expression instanceof Concat) {
            MAP.put(String.valueOf(expression.hashCode()), selectExpressionItem);
        } else if (expression instanceof SubSelect) {
            MAP.put(String.valueOf(expression.hashCode()), selectExpressionItem);
        }
        expression.accept(this);
    }

    @Override
    public void visit(GroupByElement groupByElement) {
        if (groupByElement == null)
            return;
        ExpressionList expressionList = groupByElement.getGroupByExpressionList();
        List<Expression> expressions = expressionList.getExpressions();
        for (Expression expression : expressions) {
            expression.accept(this);
        }
    }

    @Override
    public void visit(OrderByElement orderByElement) {
        if (orderByElement == null)
            return;
        orderByElement.getExpression().accept(this);
    }

    //length用户要求产生字符串的长度
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(52);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }
}
